#include <iostream>
#include <optional>
#include "tinyxml2/tinyxml2.h"


#include "db_info.h"

using namespace tinyxml2;

void create_xml_file() {
    // 创建一个新的XML文档对象
    tinyxml2::XMLDocument doc;

    XMLElement* pRoot = doc.NewElement("configuration");
    doc.InsertFirstChild(pRoot);
    XMLElement* pDatabase = doc.NewElement("database");
    pRoot->InsertEndChild(pDatabase);

    // 为<database>添加子元素
    XMLElement* pH = doc.NewElement("host");
    pH->SetText("");
    pDatabase->InsertEndChild(pH);

    XMLElement* pP = doc.NewElement("port");
    pP->SetText("");
    pDatabase->InsertEndChild(pP);

    XMLElement* pU = doc.NewElement("user");
    pU->SetText("");
    pDatabase->InsertEndChild(pU);

    XMLElement* pPass = doc.NewElement("password");
    pPass->SetText("");
    pDatabase->InsertEndChild(pPass);

    XMLElement* pD = doc.NewElement("database_name");
    pD->SetText("");
    pDatabase->InsertEndChild(pD);

    // 创建<log>元素并添加到根元素
    XMLElement* pLog = doc.NewElement("log");
    pRoot->InsertEndChild(pLog);

    // 为<log>添加子元素
    XMLElement* pLevel = doc.NewElement("level");
    pLevel->SetText("info");
    pLog->InsertEndChild(pLevel);

    // 将XML文档保存到文件
    XMLError eResult = doc.SaveFile("config.xml");

#ifdef DEBUG_PRINTS
    if (eResult == XML_SUCCESS) {
        std::cout << "XML file created successfully." << std::endl;
    }
    else {
        std::cerr << "Error creating XML file. Error code: " << eResult << std::endl;
    }
#endif

    return;
}


std::optional<DatabaseInfo*> read_database_info() {
    // 创建XML文档对象
    tinyxml2::XMLDocument doc;
    // 加载XML文件
    XMLError eResult = doc.LoadFile("config.xml");

    if (eResult != XML_SUCCESS) {
        std::cerr << "Error loading XML file." << std::endl;
        create_xml_file();
        return std::nullopt;
    }

    // 获取根元素
    XMLElement* pRoot = doc.RootElement();
    if (!pRoot) {
        std::cerr << "No root element found in the document." << std::endl;
        create_xml_file();
        return std::nullopt;
    }

    // 找到<database>元素
    XMLElement* pDatabase = pRoot->FirstChildElement("database");
    if (!pDatabase) {
        std::cerr << "No database configuration found." << std::endl;
        create_xml_file();
        return std::nullopt;
    }

    // 检查所有必需的子元素是否存在
    XMLElement* pHost = pDatabase->FirstChildElement("host");
    XMLElement* pPort = pDatabase->FirstChildElement("port");
    XMLElement* pUser = pDatabase->FirstChildElement("user");
    XMLElement* pPassword = pDatabase->FirstChildElement("password");
    XMLElement* pDbName = pDatabase->FirstChildElement("database_name");

    if (!pHost || !pPort || !pUser || !pPassword || !pDbName) {
        std::cerr << "Missing one or more required database configuration elements." << std::endl;
        create_xml_file();
        return std::nullopt;
    }

    const char* hostText = pHost->GetText();
    const char* userText = pUser->GetText();
    const char* passwordText = pPassword->GetText();
    const char* dbNameText = pDbName->GetText();
    const char* portText = pPort->GetText();

    if (!hostText || !userText || !passwordText || !dbNameText || !portText) {
        std::cerr << "One or more required database configuration elements are empty." << std::endl;
        create_xml_file();
        return std::nullopt;
    }

    std::string host(hostText);
    std::string user(userText);
    std::string password(passwordText);
    std::string dbname(dbNameText);
    int port = atoi(portText);

    return new DatabaseInfo(host, user, password, dbname, port);
}
